﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml.Linq;
using MySilverlightAlbum.Data;
using System.Windows.Browser;

namespace MySilverlightAlbum
{
    public enum MenuToggleState
    {
        ShowAll               = 0,
        HideAll               = 1,
        HideListDescription   = 2,
        HideDescription       = 3,
    }

    public partial class PhotoAlbumSite : UserControl
    {
        private const string                             HELP_TEXT = 
            "[Mouse Wheel] - Zoom In/Out | [Click] - Zoom In | [Alt + Click] - Zoom Out | [Mouse Move] - Scrool image";

        private const int                                HIDE_MENU_DURATION = 500;

        private const int                                MAIN_MENU_ROW_HEIGHT = 26;
        private const int                                HELP_ROW_HEIGHT = 14;
        private const int                                DESCRIPT_ROW_HEIGHT = 200;
        private const int                                LIST_COL_WIDTH = 54;

        private MenuToggleState                          m_toggleState = MenuToggleState.ShowAll;
        private ImageFolder                              m_currentFolder;
        private ImageFolder                              m_root;
        private ImageFolder                              m_displayedImageFolder;

        public PhotoAlbumSite(
        )
        {
            InitializeComponent();

            DataContext = this;

            mainMenu.Action += OnMainMenuAction;
            imageList.ImageSelected += OnImageSelected;
            KeyDown += OnKeyDown;

            StartDataDownload();
        }

        private void OnImageSelected(
            object                                      sender, 
            RoutedEventArgs                             e
        )
        {
            ImageFolder                                 f;
    
            f = (ImageFolder) sender;

            imageViewer.ImageUrl = f.Location;
            imageDescription.DataContext = f;
        }

        public ImageFolder CurrentImageFolder
        {
            get
            {
                return m_currentFolder;
            }
            set
            {
                m_currentFolder = value;
                
                if (value != null)
                {
                    if (String.IsNullOrEmpty(m_currentFolder.Location))
                    {
                        if (m_currentFolder.Children.Count > 0 && 
                            !String.IsNullOrEmpty(m_currentFolder.Children[0].Location))
                        {
                            m_displayedImageFolder = m_currentFolder.Children[0];
                            imageViewer.ImageUrl = m_displayedImageFolder.Location;
                        }
                    }
                    else
                    {
                        m_displayedImageFolder = m_currentFolder;
                        imageViewer.ImageUrl = m_currentFolder.Location;
                    }
                }

                imageList.CurrentFolder = value;
                imageDescription.DataContext = m_displayedImageFolder;
            }
        }

        public string CurrentControlHelp
        {
            get
            {
                return HELP_TEXT;
            }
        }

        #region Private Methods and Properties

        private void OnMainMenuAction(
            object                                      sender, 
            RoutedEventArgs                             e
        )
        {
            ExecAction(((FrameworkElement) e.OriginalSource).Name);
        }

        private void ExecAction(
            string                                      action
        )
        {
            ImageFolder                                 folder;
            string                                      url;

            switch (action)
            {
                case "contact":
                    url = m_root.MailTo;
                    HtmlPage.Window.Navigate(new Uri("mailto:" + url + 
                        "?subject=RE: YOUR PHOTOS"));
                    break;

                case "fullscreen":
                    ToggleFullScreen();
                    break;

                case "togglemenu":
                    ToggleMenus();
                    break;

                default:
                    folder = m_root.Children.Find(action);
                    if (folder != null)
                    {
                        CurrentImageFolder = folder;
                    }
                    else
                    {
                        CurrentImageFolder = m_root;
                    }
                    break;
            }

            imageViewer.Focus();
        }

        private void ToggleMenus(
        )
        {
            switch (m_toggleState)
            {
                case MenuToggleState.ShowAll:
                    m_toggleState = MenuToggleState.HideDescription;
                    menuRow.Height = new GridLength(MAIN_MENU_ROW_HEIGHT);
                    helpRow.Height = new GridLength(HELP_ROW_HEIGHT);
                    descriptionRow.Height = new GridLength(0);
                    listColumn.Width = new GridLength(LIST_COL_WIDTH);
                    break;

                case MenuToggleState.HideAll:
                    m_toggleState = MenuToggleState.ShowAll;
                    menuRow.Height = new GridLength(MAIN_MENU_ROW_HEIGHT);
                    helpRow.Height = new GridLength(HELP_ROW_HEIGHT);
                    descriptionRow.Height = new GridLength(DESCRIPT_ROW_HEIGHT);
                    listColumn.Width = new GridLength(LIST_COL_WIDTH);
                    break;

                case MenuToggleState.HideDescription:
                    m_toggleState = MenuToggleState.HideListDescription;
                    menuRow.Height = new GridLength(MAIN_MENU_ROW_HEIGHT);
                    helpRow.Height = new GridLength(HELP_ROW_HEIGHT);
                    descriptionRow.Height = new GridLength(0);
                    listColumn.Width = new GridLength(0);
                    break;

                default: // MenuToggleState.HideListDescription
                    m_toggleState = MenuToggleState.HideAll;
                    menuRow.Height = new GridLength(0);
                    helpRow.Height = new GridLength(0);
                    descriptionRow.Height = new GridLength(0);
                    listColumn.Width = new GridLength(0);
                    break;
            }
        }

        private void OnKeyDown(
            object                                      sender, 
            KeyEventArgs                                e
        )
        {
            if ((e.Key & Key.Add) == Key.Add)
            {
                imageViewer.ZoomIn();
            }
            else if ((e.Key & Key.Subtract) == Key.Subtract)
            {
                imageViewer.ZoomOut();
            }
            else if (e.Key == Key.Escape)
            {
                ExecAction("fullscreen");
            }
            else if (e.Key == Key.Enter)
            {
                ExecAction("togglemenu");
            }
        }

        private void ToggleFullScreen(
        )
        {
            Application.Current.Host.Content.IsFullScreen = 
                !Application.Current.Host.Content.IsFullScreen;

            imageViewer.Center();
        }

        #endregion

        #region Data File Load

        private void StartDataDownload(
        )
        {
            WebClient                                   client;

            client = new WebClient();
            client.OpenReadCompleted += OnDataReadCompleted;
            client.OpenReadAsync(new Uri("data.xml", UriKind.RelativeOrAbsolute));
        }

        void OnDataReadCompleted(
            object                                      sender, 
            OpenReadCompletedEventArgs                  args
        )
        {
            ImageFolder                                 root;      
            XDocument                                   doc;

            if (!args.Cancelled && args.Error == null)
            {
                doc = XDocument.Load(args.Result, LoadOptions.None);
                root = ImageFolder.FromXElement(doc.Root);
                
                if (root.Children.Count > 0)
                {
                    imageViewer.ImageUrl = root.Children[0].Location;
                }

                mainMenu.Document = root;
            }
            else
            {
                root = null;
            }

            m_root = root;
            CurrentImageFolder = root;

            imageViewer.Focus();
        }

        #endregion
    }
}
